package com.mnemonic.views;

import java.awt.Rectangle;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JButton;
import javax.swing.JDialog;

import com.mnemonic.game.Bout;
import com.mnemonic.game.Game;
import com.mnemonic.lifecycle.Lifecycle;
import com.mnemonic.player.Player;
import com.mnemonic.storage.impl.GameStorageService;
import com.mnemonic.support.swing.Dialogs;
import com.mnemonic.support.swing.Display;
import com.mnemonic.utils.Ints;
import com.mnemonic.views.field.ClockField;
import com.mnemonic.views.field.ClockField.CountdownListener;
import com.mnemonic.views.field.Field;
import com.mnemonic.views.field.MineFields;
import com.mnemonic.views.field.PlayerFields;

/**
 * 战场
 * 
 * @author lifeng
 * @date 2021/05/13
 */
public class GamePage extends JDialog implements Lifecycle, CountdownListener {

    private static final long serialVersionUID = 1L;

    /**
     * 一次游戏数据: 存储了此次游戏的所有数据
     */
    private Game game;

    /**
     * 左上边显示区域
     */
    private ClockField gameClock;
    private Field mineCount;
    private ClockField boutClock;
    private Field boutCount;

    /**
     * 右上边控制区域
     */
    private JButton penetrateOps;
    private JButton saveOps;
    private JButton pauseOps;
    private JButton finishOps;

    /**
     * 有下边 玩家区域
     */
    private PlayerFields playerFields;

    /**
     * 左下边雷区
     */
    private MineFields mineFields;

    /**
     * 游戏存档管理
     */
    private GameStorageService gameStorageService;

    /**
     * 背景音乐
     * 
     * @param game
     */
    private GameAudio gameAudio;

    /**
     * 保留当前最新的回合
     */
    private volatile Bout bout;

    public GamePage(Game game) {
        super(Display.getRoot(), false);
        this.game = game;
        this.setTitle(game.getName() + "  正在进行中...");
        Rectangle rectangle = Display.getRoot().getBounds();
        this.setBounds(rectangle.x - 35, rectangle.y + 30, rectangle.width + 70, rectangle.height);
        this.setResizable(false);
        this.setLayout(null);
        this.gameStorageService = new GameStorageService();
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                GamePage.this.destory();
            }
        });

        // 本场时间计数器
        gameClock = new ClockField("运行：");
        gameClock.setBounds(10, 10, 100, 30);
        this.add(gameClock);

        // 雷数
        mineCount = new Field("雷数：" + game.getLevel().getMine());
        mineCount.setBounds(120, 10, 100, 30);
        this.add(mineCount);

        // 回合计数器
        boutClock = new ClockField("剩余：", game.getLevel().getBoutTimeOut(), this);
        boutClock.setBounds(230, 10, 100, 30);
        this.add(boutClock);

        // 回合剩余次数
        boutCount = new Field("次数：" + game.getLevel().getBoutOps());
        boutCount.setBounds(340, 10, 100, 30);
        this.add(boutCount);

        // 透视按钮
        penetrateOps = new JButton("透视");
        penetrateOps.addActionListener((e) -> {
            this.mineFields.opsPenetrate();
        });
        penetrateOps.setBounds(535, 10, 80, 30);
        this.add(penetrateOps);
        saveOps = new JButton("归档");
        saveOps.addActionListener((e) -> {
            this.gameStorageService.save(this.game);
            Dialogs.info("操作提醒", "存档成功！");
        });
        saveOps.setBounds(625, 10, 80, 30);
        this.add(saveOps);
        pauseOps = new JButton("暂停");
        pauseOps.setBounds(715, 10, 80, 30);
        this.add(pauseOps);
        finishOps = new JButton("结束");
        finishOps.addActionListener((e) -> {
            this.destory();
        });
        finishOps.setBounds(805, 10, 80, 30);
        this.add(finishOps);

        // 雷区
        mineFields = new MineFields(this, game);
        mineFields.setBounds(10, 50, 610, 415);
        this.add(mineFields);

        // 玩家区域
        playerFields = new PlayerFields(game.getPlayers());
        playerFields.setBounds(620, 50, 270, 415);
        this.add(playerFields);

        // 开启背景音乐
        this.gameAudio = new GameAudio("start.wav");

        // 开始游戏
        this.start();
    }

    /**
     * 开启游戏：<br>
     * 1. 开启计时器, 倒计时<br>
     * 2. 初始化雷区<br>
     * 3. 开启第一回合<br>
     * 4. 开启背景音乐<br>
     */
    @Override
    public void start() {

        // 1. 开启计时器
        this.gameClock.start();
        this.boutClock.start();

        // 2. 初始化雷区
        this.initMineArea();

        // 3. 开启回合
        this.nextBout();

        // 4. 开启背景音乐
        this.gameAudio.start();
    }

    // 初始化雷区 -- 可以反复初始化根据本次游戏的level数据
    // 可以第一次仅仅是设置一个空数据
    // 用户操作第一次后，设置真实的雷区
    private void initMineArea() {

        // 布雷
        if (!this.game.getInited()) {
            this.refreshMineArea();
        }

        // 刷新画布
        this.mineFields.repaint();
    }

    /**
     * 刷新雷区
     */
    private void refreshMineArea() {
        this.game.burnMine();
    }

    /**
     * 1. 创建回合数据<br>
     * 2. 重置回合可操作数<br>
     * 3. 激活当前的玩家<br>
     * 4. 重置倒计时<br>
     */
    private void nextBout() {

        // 1. 创建回合数据
        this.bout = this.game.newBout();

        // 2. 重置回合可操作数
        // 3. 激活当前的玩家
        Display.runUI(() -> {
            boutCount.setText("次数：" + (bout.getMaxops() - bout.getOps()));
            playerFields.active(bout.getPlayer());
        });

        // 4. 重置倒计时
        this.boutClock.reset();

        // 5. 机器人自动操作
        bout.getPlayer().autoMine(this.game, (row, col) -> {
            Display.runUI(() -> {
                this.feedbackMineResult(row, col);
            });
        });
    }

    @Override
    public void destory() {
        int result = Dialogs.confirm("提醒", "确认关闭？");
        if (result == 0) {
            this.gameClock.destory();
            this.boutClock.destory();
            this.gameStorageService.save(this.game);
            this.gameAudio.close();
            this.mineFields.destory();
            new GameOver().start();
            try {
                Thread.sleep(1800);
            } catch (InterruptedException e) {
            }
            this.dispose();
        }
    }

    /**
     * 回合超时
     */
    @Override
    public void countdown(ClockField clock) {
        this.nextBout();
    }

    // 获得操作结果， 判断结果的正确性
    // 扣减雷区的数据
    // 更新显示各个区域的数据
    // 如果操作次数到了，则切换到下一回合
    public void feedbackMineResult(int row, int col) {

    }

    // 获得操作结果， 判断结果的正确性
    // 扣减雷区的数据
    // 更新显示各个区域的数据
    // 如果操作次数到了，则切换到下一回合
    public void feedbackMineResult(boolean success) {

        // 当前操作的玩家
        Player player = this.bout.getPlayer();
        player.setFaults(Ints.addI(player.getFaults(), success ? 0 : 1));
        player.setScores(Ints.addI(player.getScores(), success ? 1 : 0));
        this.playerFields.update(player);
        
        // 雷数修改
        //mineCount.setText(t);
    }

    /**
     * 游戏结束音效
     * 
     * @author lifeng
     * @date 2021/05/15
     */
    public class GameOver extends GameAudio {
        public GameOver() {
            super("gameover.wav");
        }
    }
}
